

pub const KERNEL_HEAP_SIZE: usize = 0x200_0000;
use crate::println;

use alloc::vec::Vec;
use buddy_system_allocator::LockedHeap;

#[global_allocator]
static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty();

#[alloc_error_handler]
pub fn handle_alloc_error(layout: core::alloc::Layout) -> ! {
    panic!("Heap allocation error, layout = {:?}", layout);
}

#[repr(align(4096))]
struct HeapSpace {
    buf: [u8; KERNEL_HEAP_SIZE],
}   

static mut HEAP_SPACE: HeapSpace = HeapSpace { buf: [0; KERNEL_HEAP_SIZE] };

pub fn init_heap() {
    unsafe {
        HEAP_ALLOCATOR
            .lock()
            .init(
                &mut HEAP_SPACE.buf[0] as *mut u8 as usize,
                KERNEL_HEAP_SIZE
            );
        
        crate::INFO!("Heap initialized: {} bytes at 0x{:x}", 
                   KERNEL_HEAP_SIZE, 
                   &HEAP_SPACE.buf[0] as *const u8 as usize);
    }
}


pub fn test_heap_alloc() {
    crate::INFO!("Heap allocation test start");
    let mut vec = Vec::new();
    for i in 0..1000 {
        vec.push(i);
    }
    assert_eq!(vec.len(), 1000);
    drop(vec);
    crate::INFO!("Heap allocation test passed");
}
